using System;
using System.Linq;

namespace DateTimeTests
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			if (args.Length == 0)
				//PrintTimeZoneNames ();
				TestUtcNearNewYear ();
			else
				//"2013-10-06 01:59" "AUS Eastern Standard Time"
				TestDate (args);
		}

		static void TestUtcNearNewYear ()
		{
			var tzId = "Australia/Sydney";
			var before = UtcDateForTimeZone("2009-12-31 23:59", tzId).ToString ();
			Console.WriteLine (before);
			var after = UtcDateForTimeZone("2010-01-01 00:01", tzId).ToString ();
			Console.WriteLine (after);
		}

		static void PrintTimeZoneNames ()
		{
			var tzs = TimeZoneInfo.GetSystemTimeZones ();
			var localtz = TimeZoneInfo.Local;
			var blah = TimeZoneInfo.FindSystemTimeZoneById ("Australia/Sydney");
			Console.WriteLine ("Local settings in this machine:");
			Console.WriteLine ("display: {0}, standard: {1}", localtz.DisplayName, localtz.StandardName);
			Console.WriteLine("====================");
			var dnames = (from x in tzs select x.DisplayName).ToArray();
			var snames = (from x in tzs select x.StandardName).ToArray();

			for (int i = 0; i < dnames.Length; i++) {
				Console.WriteLine ("display: {0}, standard: {1}", dnames [i], snames [i]);
			}
		}

		static void TestDate (string[] args)
		{
			var dt = UtcDateForTimeZone (args [0], args [1]);
			Console.WriteLine (dt.ToString ());
		}

		public static DateTime UtcDateForTimeZone(string isoDateTime, string timeZoneId = "UTC")
		{
			// Using TimeZoneInfo on dates far back towards the start of the christian calendar era poses problem. Don't do it if TZ = UTC
			if(timeZoneId == "UTC")
				return CreateDate(isoDateTime, "Utc");
			else
			{
				var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
				var dtun = CreateDate(isoDateTime);
				return TimeZoneInfo.ConvertTimeToUtc(dtun, tz);
			}
		}

		public static DateTime CreateDate(string isoDateTime, string datetimeKind = "")
		{
			var res = DateTime.Parse(isoDateTime);
			if (!string.IsNullOrEmpty(datetimeKind))
			{
				DateTimeKind dtk;
				if (Enum.TryParse(datetimeKind, out dtk))
					res = new DateTime(res.Ticks, dtk);
			}
			return res;
		}
	}
}
